package com.ccg.androidwebrtcclient

import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.ccg.androidwebrtcclient.ui.theme.AndroidWebrtcClientTheme
import com.google.gson.Gson
import okhttp3.Response
import okhttp3.WebSocket
import okio.ByteString
import org.webrtc.DataChannel
import org.webrtc.IceCandidate
import org.webrtc.MediaConstraints
import org.webrtc.MediaStream
import org.webrtc.PeerConnection
import org.webrtc.PeerConnectionFactory
import org.webrtc.RtpReceiver
import org.webrtc.SdpObserver
import org.webrtc.SessionDescription
import timber.log.Timber
import java.nio.ByteBuffer

/**
 * @author : C4_雍和
 * 描述 :小文件点对点传输
 * 主要功能 :
 * 维护人员 : C4_雍和
 * date : 2025/9/23 14:33
 */
class SmallFileTransmissionActivity : ComponentActivity() {
    private val context = this
    private var mWebSocketClient: WebSocketClient? = null
    val userBuyClasses by lazy { mutableStateListOf<String>() }
    private lateinit var peerConnectionFactory: PeerConnectionFactory
    private var peerConnection: PeerConnection? = null
    private val iceServers = listOf(PeerConnection.IceServer.builder("stun:stun.qq.com:3478").createIceServer())
    private var dataChannel: DataChannel? = null

    /**
     * 远程对方id
     */
    private var remotePeerId: String = ""
    private val ip: String = "192.168.1.2"
    private val userId by lazy { mutableStateOf(System.currentTimeMillis().toString()) }
    val clientStatus by lazy { mutableStateOf("") }
    private var json: String = ""

    // 使用单例Gson实例
    private val gson = Gson()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            AndroidWebrtcClientTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    var serviceUrl by remember { mutableStateOf("ws://" + ip + ":9799/chat?token=") }
                    var message by remember { mutableStateOf("") }
                    Column(
                        modifier = Modifier
                            .fillMaxSize()
                            .padding(innerPadding), horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        Text("文字点对点传输")
                        TextField(value = serviceUrl, onValueChange = {
                            serviceUrl = it
                            Timber.e("serviceUrl:    " + serviceUrl)
                        }, placeholder = {
                            Text("请输入服务器地址")
                        })
                        TextField(value = userId.value, onValueChange = {
                            userId.value = it
                            Timber.e("userId:    " + userId.value)
                        }, placeholder = {
                            Text("请输入自己的id")
                        })
                        Button(onClick = {
                            mWebSocketClient = WebSocketClient(object : okhttp3.WebSocketListener() {
                                override fun onOpen(webSocket: WebSocket, response: Response) {
                                    runOnUiThread {
                                        clientStatus.value = "连接成功 " + response.code
                                    }
                                }

                                override fun onMessage(webSocket: WebSocket, text: String) {
                                    Timber.e("" + text)
                                    handleSignalingMessage(text)
                                }

                                override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
                                }

                                override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
                                }

                                override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
                                }

                                override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                                }
                            })
                            mWebSocketClient?.connect(serviceUrl + userId.value)
                        }) {
                            Text("连接服务器")
                        }
                        Text(clientStatus.value)
                        Button(onClick = {
                            mWebSocketClient?.close(userId.value)
                            clientStatus.value = "已断开连接"
                        }) {
                            Text("与服务器断开连接")
                        }
                        LazyColumn {
                            items(count = userBuyClasses.size) {
                                Button(onClick = {
                                    remotePeerId = userBuyClasses[it]
                                    createOffer()
                                }) {
                                    Text("" + it + "   连接客户端->   " + userBuyClasses[it])
                                }
                            }
                        }
                        TextField(value = message, onValueChange = {
                            message = it
                            Timber.e("输入的内容:    " + message)
                        }, placeholder = {
                            Text("请输入要发送的消息")
                        })
                        Button(onClick = {
                            sendMessage(message)
                        }) {
                            Text("发送消息")
                        }
                    }
                }
            }
        }
        initializeWebRTC()
    }

    private fun initializeWebRTC() {
        Timber.e("initializeWebRTC1")
        // 初始化PeerConnectionFactory
        PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions.builder(this).setEnableInternalTracer(true).createInitializationOptions())
        Timber.e("initializeWebRTC2")
        val options = PeerConnectionFactory.Options()
        peerConnectionFactory = PeerConnectionFactory.builder().setOptions(options).createPeerConnectionFactory()
        Timber.e("initializeWebRTC3")
        // 创建PeerConnection
        peerConnection = peerConnectionFactory.createPeerConnection(iceServers, object : PeerConnection.Observer {
            override fun onSignalingChange(state: PeerConnection.SignalingState?) {
                Timber.e("Signaling state changed to: $state")
            }

            override fun onIceConnectionChange(state: PeerConnection.IceConnectionState?) {
                Timber.e("ICE connection state changed to: $state")
                // 可以在这里更新UI显示连接状态
                if (state == PeerConnection.IceConnectionState.COMPLETED) {
                    initDataChannel()
                }
            }

            override fun onIceConnectionReceivingChange(receiving: Boolean) {
                Timber.e("ICE connection receiving change: $receiving")
            }

            override fun onIceGatheringChange(state: PeerConnection.IceGatheringState?) {
                Timber.e("ICE gathering state changed to: $state")
                runOnUiThread {
                    clientStatus.value = "ICE gathering state changed to: $state"
                }
            }

            override fun onIceCandidate(candidate: IceCandidate?) {
                Timber.e("New ICE candidate: ${candidate?.sdp}")
                candidate?.let {
                    // 这里应该通过信令服务器发送ICE候选给对端
                    sendIceCandidate(it)
                }
            }

            override fun onIceCandidatesRemoved(candidates: Array<out IceCandidate>?) {
                Timber.e("ICE candidates removed")
            }

            override fun onAddStream(stream: MediaStream?) {
                Timber.e("Stream added: ${stream?.id}")
                // 处理远程媒体流
            }

            override fun onRemoveStream(stream: MediaStream?) {
                Timber.e("Stream removed: ${stream?.id}")
            }

            override fun onDataChannel(channel: DataChannel?) {
                Timber.e("Data channel received: ${channel?.label()}")
                dataChannel = channel
                setupDataChannel(channel)
            }

            override fun onRenegotiationNeeded() {
                Timber.e("Renegotiation needed")
                // 需要重新创建offer
                createOffer()
            }

            override fun onAddTrack(receiver: RtpReceiver?, streams: Array<out MediaStream>?) {
                Timber.e("Track added")
            }
        })
    }

    // 处理从信令服务器接收的消息
    fun handleSignalingMessage(json: String) {
        Timber.e("handleSignalingMessage:   " + json)
        try {
            val intentData = gson.fromJson(json, WebRtcBean::class.java)
            when (intentData.type) {
                "0" -> {
                    //服务器通知又有新客户端登陆了
                    userBuyClasses.add(intentData.sender)
                }

                "1" -> {
                    //服务器通知有客户端退出
                    userBuyClasses.remove(intentData.sender)
                }

                "2" -> {
                    //开始下载文件
                    Timber.e("开始下载文件")
                }

                "3" -> {
                    //下载文件结束
                    Timber.e("下载文件结束")
                }

                "OFFER" -> {
                    // 检查当前信令状态
                    if (peerConnection?.signalingState() != PeerConnection.SignalingState.STABLE) {
                        Timber.e("Cannot handle offer in current signaling state: ${peerConnection?.signalingState()}")
                        return
                    }
                    remotePeerId = intentData.sender
                    val sdp = SessionDescription(SessionDescription.Type.OFFER, intentData.description)
                    peerConnection?.setRemoteDescription(object : SdpObserver {
                        override fun onSetSuccess() {
                            Timber.e("Remote description set successfully")
                            createAnswer()
                        }

                        override fun onSetFailure(error: String) {
                            Timber.e("Failed to set remote description: $error")
                        }

                        override fun onCreateSuccess(p0: SessionDescription?) {}
                        override fun onCreateFailure(p0: String?) {}
                    }, sdp)
                }

                "ANSWER" -> {
                    val sdp = SessionDescription(SessionDescription.Type.ANSWER, intentData.description)
                    peerConnection?.setRemoteDescription(object : SdpObserver {
                        override fun onSetSuccess() {
                            Timber.e("onSetSuccess2")
                            runOnUiThread {
                                clientStatus.value = "连接成功 可以发送消息了"
                            }
                        }

                        override fun onSetFailure(error: String) {
                            Timber.e("onSetFailure    " + error)
                        }

                        override fun onCreateSuccess(p0: SessionDescription?) {
                            Timber.e("onCreateSuccess     " + gson.toJson(p0))
                        }

                        override fun onCreateFailure(p0: String?) {
                            Timber.e("onCreateFailure     " + p0)
                        }
                    }, sdp)
                }

                "CANDIDATE" -> {
                    val candidate = IceCandidate(intentData.sdpMid, intentData.sdpMLineIndex, intentData.sdp)
                    peerConnection?.addIceCandidate(candidate)
                }
            }
        } catch (e: Exception) {
            Timber.e("报错1:  " + e.message)
        }
    }


    private fun sendIceCandidate(candidate: IceCandidate) {
        Timber.e("注意!:    sendIceCandidate")
        // 实现通过信令服务器发送ICE候选的逻辑
        // 例如使用WebSocket发送JSON消息:
        // {"type": "candidate", "candidate": candidate.sdp, "sdpMid": candidate.sdpMid,
        // "sdpMLineIndex": candidate.sdpMLineIndex, "sender": localPeerId, "receiver": remotePeerId}

        val webRtcBean = WebRtcBean().apply {
            type = "CANDIDATE"
            sender = userId.value
            receiver = remotePeerId
            sdpMid = candidate.sdpMid
            sdpMLineIndex = candidate.sdpMLineIndex
            sdp = candidate.sdp
        }
        mWebSocketClient?.send(gson.toJson(webRtcBean))
    }

    private fun createOffer() {
        peerConnection?.createOffer(object : SdpObserver {
            override fun onCreateSuccess(desc: SessionDescription) {
                Timber.e("onCreateSuccess")
                peerConnection?.setLocalDescription(object : SdpObserver {
                    override fun onSetSuccess() {
                        Timber.e("onSetSuccess3")
                        // 通过信令服务器发送offer给对端
                        sendOffer(desc)
                    }

                    override fun onSetFailure(error: String) {
                        Timber.e("onSetFailure")
                    }

                    override fun onCreateSuccess(p0: SessionDescription?) {
                        Timber.e("onCreateSuccess")
                    }

                    override fun onCreateFailure(p0: String?) {
                        Timber.e("onCreateFailure")
                    }
                }, desc)
            }

            override fun onCreateFailure(error: String) {
                Timber.e("onCreateFailure:    $error")
            }

            override fun onSetSuccess() {
                Timber.e("onSetSuccess1")
            }

            override fun onSetFailure(error: String) {
                Timber.e("onSetFailure")
            }
        }, MediaConstraints().apply {
            // 可以添加自定义约束
            mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"))
            mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false"))
        })
    }

    private fun sendOffer(offer: SessionDescription) {
        Timber.e("sendOffer")
        // 实现通过信令服务器发送offer的逻辑
        // 例如使用WebSocket发送JSON消息:
        // {"type": "offer", "sdp": offer.description, "sender": localPeerId, "receiver": remotePeerId}
        val webRtcBean = WebRtcBean().apply {
            type = offer.type.toString()
            sender = userId.value
            receiver = remotePeerId
            description = offer.description
        }
        mWebSocketClient?.send(gson.toJson(webRtcBean))
    }

    private fun createAnswer() {
        peerConnection?.createAnswer(object : SdpObserver {
            override fun onCreateSuccess(desc: SessionDescription) {
                Timber.e("Answer created: ${desc.description}")
                peerConnection?.setLocalDescription(object : SdpObserver {
                    override fun onSetSuccess() {
                        Timber.e("Local description set successfully")
                        // 通过信令服务器发送answer给对端
                        sendAnswer(desc)
                    }

                    override fun onSetFailure(error: String) {
                        Timber.e("Failed to set local description: $error")
                    }

                    override fun onCreateSuccess(p0: SessionDescription?) {}
                    override fun onCreateFailure(p0: String?) {}
                }, desc)
            }

            override fun onCreateFailure(error: String) {
                Timber.e("Failed to create answer: $error")
            }

            override fun onSetSuccess() {}
            override fun onSetFailure(error: String) {}
        }, MediaConstraints())
    }

    private fun sendAnswer(answer: SessionDescription) {
        // 实现通过信令服务器发送answer的逻辑
        // 类似sendOffer方法
        Timber.e("发送答案:  " + remotePeerId)
        val webRtcBean = WebRtcBean().apply {
            type = SessionDescription.Type.ANSWER.toString()
            sender = userId.value
            receiver = remotePeerId
            description = answer.description
        }
        mWebSocketClient?.send(gson.toJson(webRtcBean))
    }

    private fun sendMessage(message: String) {
        Timber.e("sendMessage:  " + dataChannel?.state())
        runOnUiThread {
            Toast.makeText(context, "发送了:   " + message, Toast.LENGTH_SHORT).show()
        }
        if (dataChannel?.state() == DataChannel.State.OPEN) {
            val byteBuffer = ByteBuffer.wrap(message.toByteArray())
            dataChannel?.send(DataChannel.Buffer(byteBuffer, false))
        } else {
            Timber.e("Data channel is not open")
        }
    }

    private fun initDataChannel() {
        // 创建数据通道
        val init = DataChannel.Init().apply {
            ordered = true
            maxRetransmits = -1
            negotiated = false
            id = 0
            protocol = "reliable"
        }

        dataChannel = peerConnection?.createDataChannel("messageChannel", init)?.apply {
            registerObserver(object : DataChannel.Observer {
                override fun onBufferedAmountChange(amount: Long) {
                    Timber.e("Buffered amount changed: $amount")
                }

                override fun onStateChange() {
                    Timber.e("Data channel state changed: ${state()}")
                }

                override fun onMessage(buffer: DataChannel.Buffer?) {
                    buffer?.let {
                        val data = ByteArray(it.data.remaining())
                        it.data.get(data)
                        val message = String(data)
                        Timber.e("Message received2: $message")
                        // 在主线程更新UI
                        runOnUiThread {
                            Toast.makeText(context, "收到消息:   " + message, Toast.LENGTH_SHORT).show()
                            Timber.e("收到消息:   " + message)
                        }
                    }
                }
            })
        }
    }

    override fun onStop() {
        super.onStop()
        Timber.e("onStop")
        mWebSocketClient?.close(userId.value)
    }

    override fun onDestroy() {
        super.onDestroy()
        Timber.e("onDestroy")
        dataChannel?.dispose()
        peerConnection?.dispose()
        peerConnectionFactory.dispose()
    }

    private fun setupDataChannel(channel: DataChannel?) {
        channel?.registerObserver(object : DataChannel.Observer {
            override fun onBufferedAmountChange(amount: Long) {
                Timber.e("Buffered amount changed: $amount")
            }

            override fun onStateChange() {
                Timber.e("Data channel state changed: ${channel.state()}")
            }

            override fun onMessage(buffer: DataChannel.Buffer?) {
                Timber.e("onMessage")
                buffer?.let {
                    if (it.binary) {
                        Timber.e("二进制数据")
                    } else {
                        Timber.e("文本消息")
                        val data = ByteArray(it.data.remaining())
                        it.data.get(data)
                        json = String(data)
                        Timber.e("Message received1: $json")
                        runOnUiThread {
                            Toast.makeText(context, "收到消息:   " + json, Toast.LENGTH_SHORT).show()
                            Timber.e("收到消息:   " + json)
                        }
                    }
                }
            }
        })
    }
}